package com.msb.mall.product.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.msb.common.constant.ProductConstant;
import com.msb.common.utils.PageUtils;
import com.msb.common.utils.Query;
import com.msb.mall.product.dao.AttrDao;
import com.msb.mall.product.entity.AttrAttrgroupRelationEntity;
import com.msb.mall.product.entity.AttrEntity;
import com.msb.mall.product.entity.AttrGroupEntity;
import com.msb.mall.product.entity.CategoryEntity;
import com.msb.mall.product.entity.vo.AttrGroupRelationVo;
import com.msb.mall.product.entity.vo.AttrResponseVo;
import com.msb.mall.product.entity.vo.AttrVo;
import com.msb.mall.product.service.AttrAttrgroupRelationService;
import com.msb.mall.product.service.AttrGroupService;
import com.msb.mall.product.service.AttrService;
import com.msb.mall.product.service.CategoryService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    AttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    AttrGroupService attrGroupService;
    @Autowired
    CategoryService categoryService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryBastPage(Map<String, Object> params, Long catId,String attrType) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("attr_type","base".equalsIgnoreCase(attrType) ? 1 : 0);
        //更具类别
        if(catId != 0){
            queryWrapper.eq("catelog_id",catId);
        }
        //2.根据key 模糊查询
        String key = (String)params.get("key");
        if(!StringUtils.isEmpty(key)){
            queryWrapper.and((obj) ->{
                obj.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        //3.分页查询
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);

            //4.关联需要查询的类别名称，属性组名称
            List<AttrEntity> records = page.getRecords();
            List<AttrResponseVo> list = records.stream().map((attrEntity -> {
                AttrResponseVo attrResponseVo = new AttrResponseVo();
                BeanUtils.copyProperties(attrEntity, attrResponseVo);
                //查询每一条对应的类别名称，属性组名称
                CategoryEntity categoryEntity = categoryService.getById(attrEntity.getCatelogId());
                if (categoryEntity != null) {
                    attrResponseVo.setCateLogName(categoryEntity.getName());
                }
                if("base".equals(attrType)){
                    //设置属性组的名称
                    AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
                    //在关联表中找到属性组的id
                    AttrAttrgroupRelationEntity one = attrAttrgroupRelationService.getOne(
                            new QueryWrapper<AttrAttrgroupRelationEntity>()
                                    .eq("attr_id", attrEntity.getAttrId())
                    );

                    if (one != null && one.getAttrGroupId() != null) {
                        AttrGroupEntity groupEntity = attrGroupService.getById(one.getAttrGroupId());
                        if (groupEntity != null) {
                            attrResponseVo.setGroupName(groupEntity.getAttrGroupName());
                        }
                    }
                }
                return attrResponseVo;
            })).collect(Collectors.toList());
            pageUtils.setList(list);
        return pageUtils;
    }

    @Override
    public PageUtils querySalePage(Map<String, Object> params, Long catId) {
        //获取关键字
        String key = (String)params.get("key");
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        if(!StringUtils.isEmpty(key)){
            //拼接查询的条件
            queryWrapper.and((obj) ->{
                obj.eq("attr_id",key).or().like("attr_name",key);
            });
        }


        if(catId == 0){
            //不根据catId查询属性组信息
            IPage<AttrEntity> page = this.page(
                    new Query<AttrEntity>().getPage(params),
                    queryWrapper
            );
            return new PageUtils(page);
        }
        //根据列表编号来查询
        queryWrapper.eq("catelog_id",catId);
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAttr(AttrVo attr) {
        //1.保存规格参数的正常信息
        AttrEntity entity = new AttrEntity();
        BeanUtils.copyProperties(attr,entity);
        this.save(entity);
        //2.保存规格参数和属性组的对应信息
        if(attr.getAttrGroupId() !=null && attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            //设置相关的属性
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            attrAttrgroupRelationEntity.setAttrId(entity.getAttrId());
            attrAttrgroupRelationService.save(attrAttrgroupRelationEntity);
        }
    }

    /**
     * 根据规格参数id查询对应的详细信息
     * 1.规格参数的具体信息
     * 2.关联的属性组信息
     * 3.关联的类别信息
     * @param attrId
     * @return
     */
    @Override
    public AttrResponseVo getAttrInfo(Long attrId) {
        //声明返回的对象
        AttrResponseVo responseVo = new AttrResponseVo();
        //1.根据规格参数id查询规格参数的具体信息
        AttrEntity attr = this.getById(attrId);
        BeanUtils.copyProperties(attr,responseVo);
        //2.查询关联的属性组信息
        if(attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationService.getOne(
                    new QueryWrapper<AttrAttrgroupRelationEntity>()
                            .eq("attr_id", attrId)
            );
            if(relationEntity != null){
                AttrGroupEntity groupEntity = attrGroupService.getById(relationEntity.getAttrGroupId());
                responseVo.setAttrGroupId(groupEntity.getAttrGroupId());
                responseVo.setGroupName(groupEntity.getAttrGroupName());

            }
        }
        //3.查询关联的类别信息
        Long[] cateLogIds = categoryService.findCateLogIds(attr.getCatelogId());
        responseVo.setCatelogPath(cateLogIds);
        CategoryEntity category = categoryService.getById(attr.getCatelogId());
        if(category != null){
            responseVo.setCateLogName(category.getName());
        }
        return responseVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBaseAttr(AttrVo attr) {
        //1.更新规格参数的正常信息
        AttrEntity entity = new AttrEntity();
        BeanUtils.copyProperties(attr,entity);
        this.updateById(entity);
        if(entity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            //2.修改规格参数和属性组的对应信息
            if(attr.getAttrGroupId() !=null){
                AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
                //设置相关的属性
                relationEntity.setAttrGroupId(attr.getAttrGroupId());
                relationEntity.setAttrId(entity.getAttrId());
                //判断是否存在对应的关系
                long count = attrAttrgroupRelationService.count(
                        new QueryWrapper<AttrAttrgroupRelationEntity>()
                                .eq("attr_id", attr.getAttrId())
                );
                if(count > 0){
                    //说明有记录，直接更新
                    attrAttrgroupRelationService.update(relationEntity,
                            new UpdateWrapper<AttrAttrgroupRelationEntity>()
                                    .eq("attr_id",attr.getAttrId()));
                }else{
                    //没有记录直接新增
                    attrAttrgroupRelationService.save(relationEntity);
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByIdsDetails(List<Long> list) {
        //1.先删除基础表的中间表信息
        for (Long attrId :list) {
            AttrEntity entity = this.getById(attrId);
            if(entity != null && entity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
                //需要删除基础表的中间表信息
                attrAttrgroupRelationService.remove(
                        new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attrId)
                );
            }
        }
        //在删除信息表
        this.removeByIds(list);

    }

    /**
     * 根据属性组编号查询对应的基本信息
     * @param attrGroupId 属性组id
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {

        //1.根据属性组编号从 属性组和基本信息的关联表中查询出对应的属性信息
        List<AttrAttrgroupRelationEntity> list = attrAttrgroupRelationService.list(
                new QueryWrapper<AttrAttrgroupRelationEntity>()
                        .eq("attr_group_id", attrGroupId)
        );
        //2.根据属性id 数组获取对应的属性信息
        return list.stream().map((entity) -> this.getById(entity.getAttrId()))
                .filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 接触属性组和基本属性的关联关系
     * 也就是删除 属性组和属性关联表中的记录
     * @param vos
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAttrRelation(AttrGroupRelationVo[] vos) {
        //将接受的数据对象转化为AttrAttrgroupRelationEntity实体对象
        List<AttrAttrgroupRelationEntity> entities = Arrays.asList(vos).stream().map((item) ->{
            AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(item,entity);
            return entity;
        }).collect(Collectors.toList());
        //批量删除关联表中的数据
        attrAttrgroupRelationService.deleteAttrRelation( entities);
    }

    /**
     * 根据属性组的id查询出未被关联的属性信息
     * @param attrGroupId 属性组的id
     * @param params 分页参数
     * @return
     */
    @Override
    public PageUtils getAttrNoRelation(Long attrGroupId, Map<String, Object> params) {
       //1.查询所有数据
        AttrGroupEntity groupEntity = attrGroupService.getById(attrGroupId);
        //2.查询出当前分组自己所属的类别下其他的分组没有关联的的属性信息
        List<AttrGroupEntity> attrGroupList = attrGroupService.list(
                new QueryWrapper<AttrGroupEntity>()
                        .eq("catelog_id", groupEntity.getCatelogId())
        );
        //获取属性组的编号集合
        List<Long> groupIds = attrGroupList.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toList());
        //查询类别信息下的所有属性已经分配的属性信息
        List<Long> attrIds = attrAttrgroupRelationService.list(
                new QueryWrapper<AttrAttrgroupRelationEntity>()
                        .in("attr_group_id", groupIds)
        ).stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        //根据类别编号查询所有的属性信息并排除上面的属性信息
        //查询出最终返回给前端 分页 带条件查询
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>()
                .eq("catelog_id",groupEntity.getCatelogId())
                .eq("attr_type",ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if(!attrIds.isEmpty()){
            wrapper.notIn("attr_id",attrIds);
        }
        //根据key 的查询过滤
        String key  = (String)params.get("key");
        if(StringUtils.isNotEmpty(key)){
            wrapper.and((w) ->{
                w.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        //分页查询结果
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void attrBatchRelation(List<AttrGroupRelationVo> vos) {
        List<AttrAttrgroupRelationEntity> entities = vos.stream().map((m) -> {
            AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(m, entity);
            return entity;
        }).collect(Collectors.toList());
        attrAttrgroupRelationService.attrBatchRelation(entities);
    }
}
